[アップデート] AMIの作成や登録解除などのイベントがAmazon EventBridgeに送信されるようになりました

[アップデート] AMIの作成や登録解除などのイベントがAmazon EventBridgeに送信されるようになりました

地味ありがたいアップデートが来た
Clock Icon2022.05.10

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

AMIのイベントを検知したいな

こんにちは、のんピ(@non____97)です。

皆さんはAMIのイベントを検知したいと思ったことはありますか? 私はあります。

具体的にはAMIのイベントを検知して以下の処理を簡単に実装したいなと思っていました。

  1. AMIの作成が完了したら別リージョンにAMIをコピーする
  2. AMIの登録解除をしたら関連付くEBSスナップショットを削除する

特に1つ目の処理を実装する場合、AMIの作成が完了したのか定期的にAMIの状態をポーリングする必要がありました。

今回、AMIの作成や登録解除などのイベントがAmazon EventBridgeに送信されるようになりました。

これにより、上述した処理が簡単に実装できそうです。

早速試してみたので紹介します。

対象のAMIのイベント

対象のAMIのイベントは以下の3つです。

  • available : AMIが利用可能になった
  • failed : AMIの作成が失敗した
  • deregistered : AMIを登録解除した

以下のいずれかのAPIが実行されると、availableまたはfailedイベントが送信されます。

DeregisterImage APIが実行されると、deregisteredイベントが送信されます。

それぞれのイベントサンプルは以下の通りです。

{
    "version": "0",
    "id": "example-9f07-51db-246b-d8b8441bcdf0",
    "detail-type": "EC2 AMI State Change",
    "source": "aws.ec2",
    "account": "012345678901",
    "time": "yyyy-mm-ddThh:mm:ssZ",
    "region": "us-east-1",
    "resources": ["arn:aws:ec2:us-east-1::image/ami-0123456789example"],
    "detail": {
        "RequestId": "example-9dcc-40a6-aa77-7ce457d5442b",
        "ImageId": "ami-0123456789example",
        "State": "available",
        "ErrorMessage": ""
    }
}
{
    "version": "0",
    "id": "example-9f07-51db-246b-d8b8441bcdf0",
    "detail-type": "EC2 AMI State Change",
    "source": "aws.ec2",
    "account": "012345678901",
    "time": "yyyy-mm-ddThh:mm:ssZ",
    "region": "us-east-1",
    "resources": ["arn:aws:ec2:us-east-1::image/ami-0123456789example"],
    "detail": {
        "RequestId": "example-9dcc-40a6-aa77-7ce457d5442b",
        "ImageId": "ami-0123456789example",
        "State": "failed",
        "ErrorMessage": "Description of failure"
    }
}
{
    "version": "0",
    "id": "example-9f07-51db-246b-d8b8441bcdf0",
    "detail-type": "EC2 AMI State Change",
    "source": "aws.ec2",
    "account": "012345678901",
    "time": "yyyy-mm-ddThh:mm:ssZ",
    "region": "us-east-1",
    "resources": ["arn:aws:ec2:us-east-1::image/ami-0123456789example"],
    "detail": {
        "RequestId": "example-9dcc-40a6-aa77-7ce457d5442b",
        "ImageId": "ami-0123456789example",
        "State": "deregistered",
        "ErrorMessage": ""
    }
}

なお、以下AWS公式ドキュメントにも記載ありますが、AMIの登録解除が失敗した場合、deregisteredイベントは生成されません。これはDeregisterImage APIが同期処理であるためです。登録解除の失敗を検知するには、APIの操作元で対応が必要そうですね。

AMIのイベントを使って処理してみる

検証する処理

それでは、AMIのイベントを使って処理してみます。

対象の処理は以下の2つです。

  1. AMIの作成が完了したら別リージョンにAMIをコピーする
  2. AMIの登録解除をしたら関連付くEBSスナップショットを削除する

検証にあたって必要なリソースはAWS CDKで定義しました。

こちらのコードのリポジトリは以下になります。

AMIの作成が完了したら別リージョンにAMIをコピーする

それでは、まず「AMIの作成が完了したら別リージョンにAMIをコピーする」から試してみます。

AWS CDKで各種リソースをデプロイした後、以下コマンドでAMIを作成します。

$ image=$(aws ec2 create-image \
    --instance-id <EC2インスタンスID> \
    --name <EC2インスタンスID>_ami \
    | jq -r .ImageId)

しばらく待った後、AMIのステータスを確認したところ、利用可能になっていました。

AMIのステータス確認

コピーされているか確認するため、コピー先に指定した大阪リージョンのAMIを確認します。

しかし、大阪リージョンに対象のAMIは存在しませんでした。

大阪リージョンのAMI確認

CloudWatch LogsでLambda関数の実行履歴を確認したところ、Lambda関数が実行されていないようです。

また、EventBridgeルールでCloudWatch Metricsも確認しましたがデータが無く、そもそもイベントが発行されていないようでした。

実行したリージョン(us-east-1)固有の問題かと思い、他のリージョンでも動作確認してみましたが、結果は同じくAMIの利用可能になったイベントを検知することができませんでした。

イベントパターンの表記ミスかと思い、EventBridgeルールにAWS公式ドキュメントに記載のイベントパターンを指定してみましたが結果は変わらずでした。

{
 "source": ["aws.ec2"],
 "detail-type": ["EC2 AMI State Change"],
 "detail": {"State": ["available"]}
}

せっかくAMIをリージョン間コピーするLambda関数を作成したので、供養の意味を込めて手動で実行してあげます。

Lambdaのコンソールから以下イベントを設定してテストをクリックします。

{
    "version": "0",
    "id": "example-9f07-51db-246b-d8b8441bcdf0",
    "detail-type": "EC2 AMI State Change",
    "source": "aws.ec2",
    "account": "012345678901",
    "time": "yyyy-mm-ddThh:mm:ssZ",
    "region": "us-east-1",
    "resources": ["arn:aws:ec2:us-east-1::image/ami-0dd5eee736ffd8be3"],
    "detail": {
        "RequestId": "example-9dcc-40a6-aa77-7ce457d5442b",
        "ImageId": "ami-0dd5eee736ffd8be3",
        "State": "available",
        "ErrorMessage": ""
    }
}

すると、以下のようにCopyImage APIを受け付けたメッセージが出力されました。

START RequestId: ebaa7260-3552-42cb-afb6-4d439e1bee51 Version: $LATEST
2022-05-10T06:45:55.448Z	ebaa7260-3552-42cb-afb6-4d439e1bee51	INFO	response : {
  "$metadata": {
    "httpStatusCode": 200,
    "requestId": "fa997007-2adf-4a11-9ca7-d5edca33e401",
    "attempts": 1,
    "totalRetryDelay": 0
  },
  "ImageId": "ami-05e0325f7941a83ce"
}
END RequestId: ebaa7260-3552-42cb-afb6-4d439e1bee51
REPORT RequestId: ebaa7260-3552-42cb-afb6-4d439e1bee51	Duration: 2170.77 ms	Billed Duration: 2171 ms	Memory Size: 128 MB	Max Memory Used: 120 MB	Init Duration: 700.38 ms	
XRAY TraceId: 1-627a0a20-7d51ce9a7a447bbc5dae83e6	SegmentId: 1a56e6dd72cf1d4a	Sampled: true	

AMIの一覧を確認すると、確かにAMIのリージョン間コピーがされていました。

手動で実行した大阪リージョンのAMI確認

2022/5/11 17:00追記 先ほど再度試したところ、AMIの利用可能になったイベントを検知することができました。以下改めて検証内容を紹介します。

以下コマンドでAMIを作成します。

$ image=$(aws ec2 create-image \
    --instance-id i-0a1366e9501b9f068 \
    --name i-0a1366e9501b9f068_ami \
    | jq -r .ImageId)

AMIが作成され、利用可能になったことを確認します。

$ aws ec2 describe-images \
    --image-ids "$image"
{
    "Images": [
        {
            "Architecture": "x86_64",
            "CreationDate": "2022-05-11T08:18:54.000Z",
            "ImageId": "ami-03fa4e3d8880f7f67",
            "ImageLocation": "<AWSアカウントID>/i-0a1366e9501b9f068_ami",
            "ImageType": "machine",
            "Public": false,
            "OwnerId": "<AWSアカウントID>",
            "PlatformDetails": "Linux/UNIX",
            "UsageOperation": "RunInstances",
            "State": "available",
            "BlockDeviceMappings": [
                {
                    "DeviceName": "/dev/xvda",
                    "Ebs": {
                        "DeleteOnTermination": true,
                        "Iops": 3000,
                        "SnapshotId": "snap-0565aa680122ec8e1",
                        "VolumeSize": 8,
                        "VolumeType": "gp3",
                        "Throughput": 125,
                        "Encrypted": false
                    }
                },
                {
                    "DeviceName": "/dev/sdb",
                    "Ebs": {
                        "DeleteOnTermination": true,
                        "Iops": 3000,
                        "SnapshotId": "snap-094538c3ed7840ed2",
                        "VolumeSize": 1,
                        "VolumeType": "gp3",
                        "Throughput": 125,
                        "Encrypted": false
                    }
                },
                {
                    "DeviceName": "/dev/sdc",
                    "Ebs": {
                        "DeleteOnTermination": true,
                        "Iops": 3000,
                        "SnapshotId": "snap-0e487c13a1b47cee3",
                        "VolumeSize": 2,
                        "VolumeType": "gp3",
                        "Throughput": 125,
                        "Encrypted": false
                    }
                }
            ],
            "EnaSupport": true,
            "Hypervisor": "xen",
            "Name": "i-0a1366e9501b9f068_ami",
            "RootDeviceName": "/dev/xvda",
            "RootDeviceType": "ebs",
            "SriovNetSupport": "simple",
            "VirtualizationType": "hvm"
        }
    ]
}

大阪リージョンでAMIを確認したところ、確かにAMIがコピーされていました。

$ aws ec2 describe-images \
    --filters "Name=name,Values=$image" \
    --region ap-northeast-3
{
    "Images": [
        {
            "Architecture": "x86_64",
            "CreationDate": "2022-05-11T08:21:59.000Z",
            "ImageId": "ami-0019121662635c453",
            "ImageLocation": "<AWSアカウントID>/ami-03fa4e3d8880f7f67",
            "ImageType": "machine",
            "Public": false,
            "OwnerId": "<AWSアカウントID>",
            "PlatformDetails": "Linux/UNIX",
            "UsageOperation": "RunInstances",
            "State": "pending",
            "BlockDeviceMappings": [
                {
                    "DeviceName": "/dev/xvda",
                    "Ebs": {
                        "DeleteOnTermination": true,
                        "Iops": 3000,
                        "VolumeSize": 8,
                        "VolumeType": "gp3",
                        "Throughput": 125,
                        "Encrypted": false
                    }
                },
                {
                    "DeviceName": "/dev/sdb",
                    "Ebs": {
                        "DeleteOnTermination": true,
                        "Iops": 3000,
                        "VolumeSize": 1,
                        "VolumeType": "gp3",
                        "Throughput": 125,
                        "Encrypted": false
                    }
                },
                {
                    "DeviceName": "/dev/sdc",
                    "Ebs": {
                        "DeleteOnTermination": true,
                        "Iops": 3000,
                        "VolumeSize": 2,
                        "VolumeType": "gp3",
                        "Throughput": 125,
                        "Encrypted": false
                    }
                }
            ],
            "EnaSupport": true,
            "Hypervisor": "xen",
            "Name": "ami-03fa4e3d8880f7f67",
            "RootDeviceName": "/dev/xvda",
            "RootDeviceType": "ebs",
            "SriovNetSupport": "simple",
            "VirtualizationType": "hvm"
        }
    ]
}

CloudWatch LogsでAMIをコピーするLambda関数の実行履歴を確認したところ、実行した形跡がありました。

START RequestId: 80be7935-eeb2-45af-89b9-6702a5760886 Version: $LATEST
2022-05-11T08:21:59.748Z	80be7935-eeb2-45af-89b9-6702a5760886	INFO	response : 
{
    "$metadata": {
        "httpStatusCode": 200,
        "requestId": "b52b8bfc-ecbf-48b4-bdd7-2d565d249ee2",
        "attempts": 1,
        "totalRetryDelay": 0
    },
    "ImageId": "ami-0019121662635c453"
}

END RequestId: 80be7935-eeb2-45af-89b9-6702a5760886
REPORT RequestId: 80be7935-eeb2-45af-89b9-6702a5760886	Duration: 2126.21 ms	Billed Duration: 2127 ms	Memory Size: 128 MB	Max Memory Used: 120 MB	Init Duration: 685.48 ms	
XRAY TraceId: 1-627b7224-51b579e17a60cfc53cee2378	SegmentId: 025c8a826926f1d1	Sampled: true

当初AMIの利用可能のイベントを検知できなかったのは、たまたまだったようですね。

AMIの登録解除をしたら関連付くEBSスナップショットを削除する

次に、「AMIの登録解除をしたら関連付くEBSスナップショットを削除する」を試してみます。

以下コマンドで先ほど作成したAMIを登録解除します。

$ aws ec2 deregister-image \
    --image-id "$image"

実行後にCloudWatch LogsでLambda関数の実行履歴を確認したところ、対象のAMIに関連付くEBSスナップショットは確かに削除されていそうでした。

START RequestId: 8986e46e-dffe-4ee8-a4ee-ace4dc888c07 Version: $LATEST
2022-05-10T06:53:25.544Z	8986e46e-dffe-4ee8-a4ee-ace4dc888c07	INFO	describeSnapshotsCommandResponse : 
{
    "$metadata": {
        "httpStatusCode": 200,
        "requestId": "ad99a42d-c288-4d7d-8e37-d67c3c3240b7",
        "attempts": 1,
        "totalRetryDelay": 0
    },
    "Snapshots": [
        {
            "Description": "Created by CreateImage(i-00a53ab2ad68af3c5) for ami-0dd5eee736ffd8be3",
            "Encrypted": false,
            "OwnerId": "<AWSアカウントID>",
            "Progress": "100%",
            "SnapshotId": "snap-07a4f312e15a1243c",
            "StartTime": "2022-05-10T06:32:17.193Z",
            "State": "completed",
            "VolumeId": "vol-038351192fbbc98b3",
            "VolumeSize": 1,
            "StorageTier": "standard"
        },
        {
            "Description": "Created by CreateImage(i-00a53ab2ad68af3c5) for ami-0dd5eee736ffd8be3",
            "Encrypted": false,
            "OwnerId": "<AWSアカウントID>",
            "Progress": "100%",
            "SnapshotId": "snap-0b202f3be3817d681",
            "StartTime": "2022-05-10T06:32:17.193Z",
            "State": "completed",
            "VolumeId": "vol-054a49873ea442962",
            "VolumeSize": 8,
            "StorageTier": "standard"
        },
        {
            "Description": "Created by CreateImage(i-00a53ab2ad68af3c5) for ami-0dd5eee736ffd8be3",
            "Encrypted": false,
            "OwnerId": "<AWSアカウントID>",
            "Progress": "100%",
            "SnapshotId": "snap-00572020c97cce254",
            "StartTime": "2022-05-10T06:32:17.193Z",
            "State": "completed",
            "VolumeId": "vol-0ab6f1f19d8b6802c",
            "VolumeSize": 2,
            "StorageTier": "standard"
        }
    ]
}

2022-05-10T06:53:25.563Z	8986e46e-dffe-4ee8-a4ee-ace4dc888c07	INFO	delete snapshotId : snap-07a4f312e15a1243c
2022-05-10T06:53:25.584Z	8986e46e-dffe-4ee8-a4ee-ace4dc888c07	INFO	delete snapshotId : snap-0b202f3be3817d681
2022-05-10T06:53:25.584Z	8986e46e-dffe-4ee8-a4ee-ace4dc888c07	INFO	delete snapshotId : snap-00572020c97cce254
END RequestId: 8986e46e-dffe-4ee8-a4ee-ace4dc888c07
REPORT RequestId: 8986e46e-dffe-4ee8-a4ee-ace4dc888c07	Duration: 837.38 ms	Billed Duration: 838 ms	Memory Size: 128 MB	Max Memory Used: 120 MB	Init Duration: 681.74 ms	
XRAY TraceId: 1-627a0be3-0ea3a69b0d841550410c3915	SegmentId: 39358d847b43adcd	Sampled: true	

実際にEBSスナップショット一覧を確認したところ、登録解除したAMIに関連付くEBSスナップショットは全て削除されていました。

地味ありがたいアップデートが来た

AMIの作成や登録解除などのイベントがAmazon EventBridgeに送信されるようになったアップデートを紹介しました。

AMIの作成や登録解除が終わったことをトリガーに後続の処理を実行したいんだよな〜」と思っていた方には朗報ですね。

この記事が誰かの助けになれば幸いです。

以上、AWS事業本部 コンサルティング部の のんピ(@non____97)でした!

この記事をシェアする

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.